#include "scenariogenerator.h"

ScenarioGenerator* ScenarioGenerator::instance = NULL;

ScenarioGenerator::ScenarioGenerator() {
	this->parser = NULL;
	this->distribution = NULL;
}

ScenarioGenerator::~ScenarioGenerator() {
	if (this->distribution!=NULL) delete this->distribution;
	if (this->parser!=NULL) delete this->parser;
	if (this->instance!=NULL) this->instance =NULL;
	
	this->distribution = NULL;
	this->parser = NULL;

}

ScenarioGenerator* ScenarioGenerator::getInstance() {
	if (instance==NULL) {
		instance = new ScenarioGenerator();
	}
	return instance;
}

Scenario *ScenarioGenerator::makeScenarioFromModel(const char *model_file) {
	this->parser = new XMLParser(model_file);
	this->parser->parse();

	this->distribution = new StatisticDistribution(StatisticDistribution::UNIFORM);
	
	/*Limits*/
	long int lower;
	long int upper;
	long double cpuSpeedLower;
	long double cpuSpeedUpper;
	

	/*------------Instance the Grid----------*/
	Grid *grid = new Grid("SimulatedGrid");
	
	//Create the sites
	lower = atoi(parser->getParameter(NUMBER_OF_SITES,LOWER_BOUND));
	upper = atoi(parser->getParameter(NUMBER_OF_SITES,UPPER_BOUND));

	
	int numberOfSites = this->distribution->next(lower, upper);
	long double gridSpeed = atof(parser->getParameter(GRID_SPEED, VALUE));
	int gridProcessorsOnBaseSite = atoi(parser->getParameter(NUMBER_OF_SITES,GRID_PROCESSORS_ON_BASESITE));

	long double siteSpeed;
	if (gridProcessorsOnBaseSite==1) {//Base Site is a normal site
		siteSpeed = gridSpeed/numberOfSites;		
	} else if (gridProcessorsOnBaseSite==0){//Base Site is an empty site (it has only 1 storage and 1 base processor)
		siteSpeed = gridSpeed/(numberOfSites-1);
	} else {
		throw std::runtime_error("Parameter GridProcessorsOnBaseSite must be \"1\" or \"0\" ");
	}
	
	
	createSites(grid,numberOfSites);

	/*get the limit of relative speed of processors*/
	cpuSpeedLower = atof(parser->getParameter(CPU_RELATIVESPEED,LOWER_BOUND));
	cpuSpeedUpper = atof(parser->getParameter(CPU_RELATIVESPEED,UPPER_BOUND));

	lower = atoi(parser->getParameter(GRID_HETEROGENEITY,LOWER_BOUND));
	upper = atoi(parser->getParameter(GRID_HETEROGENEITY,UPPER_BOUND));
	
	int indexGH = this->distribution->next(lower, upper);
	char *nameGH = new char[10];
	sprintf(nameGH, "GH.%d", indexGH);
	
	long double gridHeterogeneity = atof(parser->getParameter(GH,VALUE, nameGH));

	cpuSpeedLower = (cpuSpeedLower - gridHeterogeneity);
	cpuSpeedUpper = (cpuSpeedUpper + gridHeterogeneity);
	
	delete nameGH;
	

//	lower = atoi(parser->getParameter(CPU_TRACEFILE,LOWER_BOUND));
//	upper = atoi(parser->getParameter(CPU_TRACEFILE,UPPER_BOUND));
	int traceIndex = 0;
	/*Add processors to sites according to siteSpeed value*/
	for (int n = 0; n < grid->getNumberOfSites(); n++) {

		//If base site is empty
		if ((n==0) && (gridProcessorsOnBaseSite==0)) continue;
		
		Site *site = grid->getSiteByIndex(n);
		long double currentSpeed = 0.0;

		while (currentSpeed < siteSpeed) {
			char *cpu_trace = new char[200];
			char *cpu_error = new char[200];
			char *cpu_forecast = NULL;//new char[200];			

//			int traceIndex = this->distribution->next(lower, upper);

			sprintf(cpu_trace,"%s.%d",parser->getParameter(CPU_TRACEFILE,NAME),traceIndex);
			sprintf(cpu_error,"%s.%d",parser->getParameter(CPU_TRACEFILE,ERROR),traceIndex);
//			sprintf(cpu_forecast,"%s.%d",parser->getParameter(CPU_FORECASTFILE,NAME),traceIndex);

			traceIndex++;
			
			//initial offset
			long double offset = this->distribution->next((long double)1, (long double)350000);
			long double speed = this->distribution->next(cpuSpeedLower, cpuSpeedUpper);

			site->addProcessor(speed, cpu_trace, offset, cpu_error, cpu_forecast);
			
			currentSpeed += speed;
			
			delete cpu_trace;
			delete cpu_error;
			delete cpu_forecast;
			
		}

	}
	/*--------------------------------------*/

	/*------------Instance the Job----------*/
	const char *jobName = parser->getParameter(APPLICATION_NAME, NAME);
	long double inputJobSize = atof(parser->getParameter(APPLICATION_INPUTSIZE, VALUE));	
	long double input_tpt = atof(parser->getParameter(INPUT_COMPUTATION_THROUGHPUT, VALUE));
	long double output_tpt = atof(parser->getParameter(OUTPUT_COMPUTATION_THROUGHPUT, VALUE));	
	
	Job *job = new Job(jobName, input_tpt, output_tpt);
	
	delete jobName;
	
	int adaptive = atoi(parser->getParameter(PARTIONER, VALUE));

	AdaptivePartitioner *partioner = NULL;

	long double averageTaskDIG = -1;
	long double averageTaskDOG = -1;
	long double inputHeterogeneity = -1;
	long double outputHeterogeneity = -1;

	
	if (adaptive==1) {
		long double lower2;
		long double upper2;
		//GI
		lower2 = atof(parser->getParameter(GI,LOWER_BOUND));
		upper2 = atof(parser->getParameter(GI,UPPER_BOUND));
		
		long double gi = this->distribution->next(lower2, upper2) / 100;
		
		//GF
		lower2 = atof(parser->getParameter(GF,LOWER_BOUND));
		upper2 = atof(parser->getParameter(GF,UPPER_BOUND));

		long double gf = this->distribution->next(lower2, upper2) / 100;

		//DI
		lower2 = atof(parser->getParameter(DI,LOWER_BOUND));
		upper2 = atof(parser->getParameter(DI,UPPER_BOUND));

		long double di = this->distribution->next(lower2, upper2) / 100;

		//DR
		lower2 = atof(parser->getParameter(DR,LOWER_BOUND));
		upper2 = atof(parser->getParameter(DR,UPPER_BOUND));

		long double dr = this->distribution->next(lower2, upper2) / 100;
		
		//V
		lower2 = atof(parser->getParameter(V,LOWER_BOUND));
		upper2 = atof(parser->getParameter(V,UPPER_BOUND));
		
		long double v = this->distribution->next(lower2, upper2) / 100;

		//W
		lower = atoi(parser->getParameter(W,LOWER_BOUND));
		upper = atoi(parser->getParameter(W,UPPER_BOUND));

		int w = this->distribution->next(lower, upper);
		
		partioner = new AdaptivePartitioner(inputJobSize*gi,inputJobSize*gf,di,dr,v,w);
		partioner->configure_workload(inputJobSize, job, grid);
		
	} else {
		
		/*Add taks to Job*/
		//Determine the number Of tasks according to their sizes
		lower = atoi(parser->getParameter(APPLICATION_GROUP,LOWER_BOUND));
		upper = atoi(parser->getParameter(APPLICATION_GROUP,UPPER_BOUND));
	
	
		//The group (average task size)
		int indexDIGDOG = this->distribution->next(lower, upper);
		char *nameDIG = new char[10];
		char *nameDOG = new char[10];	
		sprintf(nameDIG, "DIG.%d", indexDIGDOG);
		sprintf(nameDOG, "DOG.%d", indexDIGDOG);	
	
	
		averageTaskDIG = atof(parser->getParameter(DATA_INPUT_GROUP,VALUE, nameDIG));
		averageTaskDOG = atof(parser->getParameter(DATA_OUTPUT_GROUP,VALUE, nameDOG));
		
		delete nameDIG;
		delete nameDOG;
	
		//job heterogeneity
		lower = atoi(parser->getParameter(APPLICATION_HETEROGENEITY,LOWER_BOUND));
		upper = atoi(parser->getParameter(APPLICATION_HETEROGENEITY,UPPER_BOUND));
		//The group (average task size)
		int indexInputOutputAH = this->distribution->next(lower, upper);
		char *nameInputAH = new char[10];
		char *nameOutputAH = new char[10];	
		sprintf(nameInputAH, "IAH.%d", indexInputOutputAH);
		sprintf(nameOutputAH, "OAH.%d", indexInputOutputAH);	
	
		inputHeterogeneity = atof(parser->getParameter(INPUT_AH,VALUE, nameInputAH));
		outputHeterogeneity = atof(parser->getParameter(OUTPUT_AH,VALUE, nameOutputAH));
		
		delete nameInputAH;
		delete nameOutputAH;
		
		//Limits of distributions of tasks' data
		long double taskDIGlower = averageTaskDIG * (1 - ( ( inputHeterogeneity / 100) / 2));
		long double taskDIGupper = averageTaskDIG * (1 + ( ( inputHeterogeneity / 100) / 2));
	
		long double taskDOGlower = averageTaskDOG * (1 - ( ( outputHeterogeneity / 100) / 2));
		long double taskDOGupper = averageTaskDOG * (1 + ( ( outputHeterogeneity / 100) / 2));
		
		long double currentInputSize = 0.0;
	
		while (currentInputSize < inputJobSize) {
			long double dataInputSize = this->distribution->next(taskDIGlower, taskDIGupper);
			long double dataOutputSize = this->distribution->next(taskDOGlower, taskDOGupper);
			job->addTask(dataInputSize, dataOutputSize);
			currentInputSize+= dataInputSize;
		}


	}


  	/*--------------------------------------*/

	/*---------Instance the scenario---------*/
	//get the number Of executions
	lower = atoi(parser->getParameter(NUMBER_OF_EXECUTIONS,LOWER_BOUND));
	upper = atoi(parser->getParameter(NUMBER_OF_EXECUTIONS,UPPER_BOUND));
	int numberOfExecutions = this->distribution->next(lower, upper);
	
	
//	long double lowerErr = atof(parser->getParameter(ERROR_RATE,LOWER_BOUND));
//	long double upperErr = atof(parser->getParameter(ERROR_RATE,UPPER_BOUND));
	
	long double error_rate = 1;//this->distribution->next(lowerErr, upperErr);

	char *scenarioname = new char[80];
	sprintf(scenarioname, "%s.%d.%Lf", parser->getParameter(SCENARIO,NAME), numberOfExecutions, this->distribution->getSeed());
	
	Scenario *scene = new Scenario(scenarioname,job, grid ,numberOfExecutions, this->distribution->getSeed(), error_rate);
	
	delete scenarioname;
	
	scene->setJobInputSize(inputJobSize);
	scene->setAverageTaskInputSize(averageTaskDIG);
	scene->setAverageTaskOutputSize(averageTaskDOG);
	scene->setInputHeterogeneity(inputHeterogeneity);
	scene->setOutputHeterogeneity(outputHeterogeneity);
	scene->setAdaptivePartioner(partioner);
	
	scene->setGridSpeed(gridSpeed);
	scene->setGridHeterogeneity(gridHeterogeneity);
	
  	/*--------------------------------------*/
  		
	/*Release memory used by parser*/
	delete this->parser;
	this->parser = NULL;

	return scene;
}

Scenario *ScenarioGenerator::makeScenarioFromDescription(const char *description_file, double gridUnavailability) {
	
	/*Parse the XML file*/
	this->parser = new XMLParser(description_file);
	this->parser->parse();
	
	/*Instance the Grid*/
	Grid *g = new Grid(parser->getParameter(GRID, NAME));
	//Gets the number of sites of the grid
	int numberOfSites = atoi(parser->getParameter(GRID,NUMBER_OF_SITES));
	
	//Add the sites to the grid
	this->addSitesToGrid(g,numberOfSites);
		
	/*Add processors to each site*/
	for (int s = 0; s < g->getNumberOfSites(); s++) {
		Site *curr_site = g->getSiteByIndex(s);
		int numberOfProcessors = atoi(parser->getParameter(SITE,NUMBER_OF_PROCESSORS, curr_site->getDomain()));
		this->addProcessorsToSite(curr_site, numberOfProcessors);
	}
	
	/*Instance the Job*/
	const char *jobname = parser->getParameter(JOB,NAME);
	long double inputJobSize = atof(parser->getParameter(APPLICATION_INPUTSIZE, VALUE));
	int numberOfTasks = atoi(parser->getParameter(JOB, NUMBER_OF_TASKS));
	long double inputData_tpt = atof(parser->getParameter(JOB, INPUT_TPT));
	long double outputData_tpt = atof(parser->getParameter(JOB, OUTPUT_TPT));
	
	Job *j = new Job(jobname,inputData_tpt, outputData_tpt);
	
	delete jobname;
	
	int adaptive = atoi(parser->getParameter(PARTIONER, VALUE));

	AdaptivePartitioner *partioner = NULL;
	
	if (adaptive==1) {
		long double gi = atof(parser->getParameter(GI, VALUE));
		long double gf = atof(parser->getParameter(GF, VALUE));
		long double di = atof(parser->getParameter(DI, VALUE));
		long double dr = atof(parser->getParameter(DR, VALUE));
		long double v = atof(parser->getParameter(V, VALUE));
		int w = atoi(parser->getParameter(W, VALUE));
		
		partioner = new AdaptivePartitioner(gi,gf,di,dr,v,w);
		partioner->configure_workload(inputJobSize, j, g);
	}

	//Add Tasks to the job
	char *taskname = new char [20];
	for (int t = 0; t< numberOfTasks; t++) {
		sprintf(taskname, "task_%d",(t+1));
		long double inputDataSize =  atof (parser->getParameter(TASK,INPUT_SIZE,taskname));
		long double outputDataSize =  atof (parser->getParameter(TASK,OUTPUT_SIZE,taskname));
		j->addTask(inputDataSize, outputDataSize);
	}
	
	delete taskname;

	/*Instance the scenario*/
	const char *scenarioname = parser->getParameter(SCENARIO,NAME);
	int numberOfExecutions = atoi(parser->getParameter(SCENARIO,NUMBER_OF_EXECUTIONS));
	long double scenarioSeed = atof(parser->getParameter(SCENARIO,SEED));
	long double scenarioError_rate = atof(parser->getParameter(SCENARIO,ERROR_RATE));
	
	/*Checks Grid site UnAvailability percentage*/
	int numberOfUnavailableSites = (int) round (g->getNumberOfSites() * (gridUnavailability/100));

	for (int siteIndex = 0; numberOfUnavailableSites > 0; siteIndex++) {
		Site *curr_site = g->getSiteByIndex(siteIndex);
		if (curr_site->getNumberOfProcessors()>0) {
			curr_site->setAllInformationNotAvailable();
			numberOfUnavailableSites--;			
		}
	}
	///////////
	
	
	Scenario *scene = new Scenario(scenarioname, j, g, numberOfExecutions, scenarioSeed, scenarioError_rate);
	
	delete scenarioname;
	
	/*Set the scenario distribution values*/
	scene->setJobInputSize(atof(parser->getParameter(APPLICATION_INPUTSIZE,VALUE)));
	scene->setAverageTaskInputSize(atof (parser->getParameter(DATA_INPUT_GROUP, VALUE)));
	scene->setAverageTaskOutputSize(atof(parser->getParameter(DATA_OUTPUT_GROUP, VALUE)));
	scene->setInputHeterogeneity(atof(parser->getParameter(INPUT_AH, VALUE)));
	scene->setOutputHeterogeneity(atof(parser->getParameter(OUTPUT_AH, VALUE)));
	scene->setGridSpeed(atof(parser->getParameter(GRID_SPEED, VALUE)));
	scene->setGridHeterogeneity(atof(parser->getParameter(GRID_HETEROGENEITY, VALUE)));
	scene->setAdaptivePartioner(partioner);
	/*---------------------------*/
		
	/*Release memory used by parser*/
	delete this->parser;
	this->parser = NULL;
	
	return scene;
}

void ScenarioGenerator::addSitesToGrid(Grid *g, int numberOfSites) {
	for (int s = 0; s<numberOfSites; s++) {
		char *sitename = new char[20];
		char *linkname = new char[50];	
		sprintf(sitename, "site%d",(s+1));					
		/*get parameters of the site from xml*/
		const char *intralink_bw = parser->getParameter(SITE, SITE_BANDWIDTH_TRACE,sitename);
		const char *intralink_bw_forecast = NULL;//parser->getParameter(SITE, SITE_BANDWIDTH_FORECAST,sitename);
		const char *intralink_bw_error = parser->getParameter(SITE, SITE_BANDWIDTH_ERROR, sitename);
		const char *interlink_lat = NULL;
		const char *interlink_bw = NULL;
		const char *interlink_bw_lim = NULL;
		const char *interlink_lat_forecast = NULL;
		const char *interlink_bw_forecast = NULL;
		const char *interlink_bw_lim_forecast = NULL;
		const char *interlink_lat_error = NULL;
		const char *interlink_bw_error = NULL;
		
		long double intralinkoffset = atof(parser->getParameter(SITE, LINK_OFFSET, sitename));
		long double interlinkoffset = 0;		
		/*First site does not have interlink parameters*/		
		if (s>0) {
			sprintf(linkname, "interlink_site1_%s",sitename);			
			interlink_lat = parser->getParameter(LINK,LAT_TRACE,linkname);
			interlink_bw = parser->getParameter(LINK,BANDWIDTH_TRACE,linkname);			
			interlink_bw_lim = parser->getParameter(LINK,BANDWIDTH_LIMIT_TRACE,linkname);						

//			interlink_lat_forecast = parser->getParameter(LINK,LAT_FORECAST,linkname);
//			interlink_bw_forecast = parser->getParameter(LINK,BANDWIDTH_FORECAST,linkname);			
//			interlink_bw_lim_forecast = parser->getParameter(LINK,BANDWIDTH_LIMIT_FORECAST,linkname);
			
			interlink_lat_error = parser->getParameter(LINK, LAT_ERROR, linkname);
			interlink_bw_error = parser->getParameter(LINK, BANDWIDTH_ERROR, linkname);

			interlinkoffset = atof(parser->getParameter(LINK, LINK_OFFSET, linkname));

		}
		/*Add site to grid*/
		g->addSite(sitename, intralink_bw, intralinkoffset, interlink_lat, interlinkoffset, interlink_bw, interlinkoffset, interlink_bw_lim, interlinkoffset, intralink_bw_error, interlink_lat_error, interlink_bw_error, intralink_bw_forecast, interlink_lat_forecast, interlink_bw_forecast, interlink_bw_lim_forecast);
		delete linkname;
		delete sitename;
	}
	
	
}

void ScenarioGenerator::addProcessorsToSite(Site *s, int numberOfProcessors) {	
	for (int p = 0; p<numberOfProcessors; p++) {
		char *processorname = new char[80];			
		sprintf(processorname, "processor_%d_%s",(p+1),s->getDomain());
		long double cpu_speed = atof(parser->getParameter(PROCESSOR,CPU_SPEED,processorname));
		const char *cpu_trace = parser->getParameter(PROCESSOR,CPU_TRACE,processorname);
		const char *cpu_error = parser->getParameter( PROCESSOR, CPU_ERROR, processorname );
		const char *cpu_forecast = NULL;//parser->getParameter(PROCESSOR,CPU_FORECAST,processorname);
		long double cpu_offset = atof(parser->getParameter(PROCESSOR,CPU_OFFSET,processorname));
		
		//add processor to site
		s->addProcessor(cpu_speed, cpu_trace, cpu_offset, cpu_error, cpu_forecast);
		delete processorname;
	}
}

void ScenarioGenerator::createSites(Grid *grid, int numberOfSites) {
	for (int s = 0; s < numberOfSites; s++) {
		char *sitename = new char[20];
		sprintf(sitename, "site%d",(s+1));					
		/*get parameters of the site from xml*/
		char *intralink_bw = new char[200];
		char *intralink_bw_forecast = NULL;//new char[200];
		char *intralink_bw_error = new char[200];
		sprintf(intralink_bw,"%s.%d",parser->getParameter(INTRALINK_TRACEFILE,BANDWIDTH_TRACE),(s+1));
//		sprintf(intralink_bw_forecast,"%s.%d",parser->getParameter(INTRALINK_FORECASTFILE,BANDWIDTH_FORECAST),(s+1));		
		sprintf(intralink_bw_error,"%s.%d",parser->getParameter(INTRALINK_TRACEFILE,BANDWIDTH_ERROR), (s+1));
		char *interlink_lat = new char[200];
		char *interlink_bw = new char[200];
		char *interlink_bw_lim = new char[200];
		char *interlink_lat_forecast = NULL;//new char[200];
		char *interlink_bw_forecast = NULL;//new char[200];
		char *interlink_bw_lim_forecast = NULL;//new char[200];
		char *interlink_lat_error = new char[200];
		char *interlink_bw_error = new char[200];
		
		/*First site does not have interlink parameters*/		
		if (s > 0) {
			sprintf(interlink_lat,"%s.1.%d",parser->getParameter(INTERLINK_TRACEFILE,LAT_TRACE), (s+1));
			sprintf(interlink_bw,"%s.1.%d",parser->getParameter(INTERLINK_TRACEFILE,BANDWIDTH_TRACE), (s+1));			
			sprintf(interlink_bw_lim,"%s.1.%d",parser->getParameter(INTERLINK_TRACEFILE,BANDWIDTH_LIMIT_TRACE), (s+1));			
//			sprintf(interlink_lat_forecast,"%s.1.%d",parser->getParameter(INTERLINK_FORECASTFILE,LAT_FORECAST), (s+1));
//			sprintf(interlink_bw_forecast,"%s.1.%d",parser->getParameter(INTERLINK_FORECASTFILE,BANDWIDTH_FORECAST), (s+1));			
//			sprintf(interlink_bw_lim_forecast,"%s.1.%d",parser->getParameter(INTERLINK_FORECASTFILE,BANDWIDTH_LIMIT_FORECAST), (s+1));
			sprintf(interlink_bw_error,"%s.1.%d",parser->getParameter(INTERLINK_TRACEFILE,BANDWIDTH_ERROR), (s+1));
			sprintf(interlink_lat_error,"%s.1.%d",parser->getParameter(INTERLINK_TRACEFILE,LAT_ERROR), (s+1));			
		} else {
			interlink_lat = NULL;
			interlink_bw = NULL;
			interlink_bw_lim = NULL;
//			interlink_lat_forecast = NULL;
//			interlink_bw_forecast = NULL;
//			interlink_bw_lim_forecast = NULL;
			interlink_lat_error = NULL;
			interlink_bw_error = NULL;
		}
		
		/*Add site to grid*/
		long double linkoffset = this->distribution->next((long double)1, (long double)350000);
		grid->addSite(sitename, intralink_bw, linkoffset, interlink_lat, linkoffset, interlink_bw, linkoffset, interlink_bw_lim, linkoffset, intralink_bw_error, interlink_lat_error, interlink_bw_error, intralink_bw_forecast, interlink_lat_forecast, interlink_bw_forecast, interlink_bw_lim_forecast);
		
		delete sitename;
		delete intralink_bw;
		delete interlink_lat;
		delete interlink_bw;
		delete interlink_bw_lim;
		delete intralink_bw_forecast;
		delete interlink_lat_forecast;
		delete interlink_bw_forecast;
		delete interlink_bw_lim_forecast;
		delete intralink_bw_error;
		delete interlink_lat_error;
		delete interlink_bw_error;
		
	}

}

Scenario *ScenarioGenerator::convertScenario(const char *sourceScenario_description, const char *resultScenario_description) {
	/*Parse the XML file*/
	this->parser = new XMLParser(resultScenario_description);
	this->parser->parse();
	
	XMLParser *sourceParser = new XMLParser(sourceScenario_description);
	sourceParser->parse();

	/*Instance the Grid*/
	Grid *g = new Grid(parser->getParameter(GRID, NAME));
	//Gets the number of sites of the grid
	int numberOfSites = atoi(parser->getParameter(GRID,NUMBER_OF_SITES));
	
	//Add the sites to the grid
	this->addSitesToGrid(g,numberOfSites);

	/*Add processors to each site*/
	int globalProcIndex = 0;
	for (int s = 1; s<g->getNumberOfSites(); s++) {
		Site *curr_site = g->getSiteByIndex(s);
		char *site_name = new char[30];
		sprintf(site_name,"domain_%d",(s-1));
		int numberOfProcessors = atoi(sourceParser->getParameter(SITE,NUMBER_OF_PROCESSORS, site_name));		
		

		for (int p = 0; p < numberOfProcessors; p++) {
			char *processorname = new char[80];			
			sprintf(processorname, "processor_%d_%s",(p+1),curr_site->getDomain());
			char *cpu_trace = new char[200];
			sprintf(cpu_trace,"./cputrace.%d",globalProcIndex);//parser->getParameter(PROCESSOR,CPU_TRACE,processorname);
			char *cpu_forecast = new char[200];
			sprintf(cpu_forecast,"./cpuforecast.%d",globalProcIndex);//parser->getParameter(PROCESSOR,CPU_TRACE,processorname);
			sprintf(processorname, "GridMachine_%d.%s",(p),site_name);
			long double cpu_speed = atof(sourceParser->getParameter(PROCESSOR,"relativeSpeed",processorname));
			long double cpu_offset = atof(sourceParser->getParameter(PROCESSOR,"cpuOffset",processorname));

			//add processor to site
			curr_site->addProcessor(cpu_speed, cpu_trace, cpu_offset, cpu_forecast);
			delete processorname;
			delete cpu_trace;
			delete cpu_forecast;

			globalProcIndex++;
		}


		delete site_name;		

	}

	/*Instance the Job*/
	const char *jobname = parser->getParameter(JOB,NAME);
	int numberOfTasks = atoi(sourceParser->getParameter("Tasks", "number"));
	long double inputData_tpt = atof(parser->getParameter(JOB, INPUT_TPT));
	long double outputData_tpt = atof(parser->getParameter(JOB, OUTPUT_TPT));	
	
	Job *j = new Job(jobname,inputData_tpt, outputData_tpt);
	
	delete jobname;
	
	//Add Tasks to the job
	char *data_name = new char [20];
	int d = 1;
	for (int t = 0; t< numberOfTasks; t++) {
		sprintf(data_name, "data_%d",(d));
		long double inputDataSize =  atof (sourceParser->getParameter("Data","size",data_name));
		long double outputDataSize =  0;//atof (parser->getParameter(TASK,OUTPUT_SIZE,taskname));
		j->addTask(inputDataSize, outputDataSize);
		d+=2;
	}
	delete data_name;

	
	/*Instance the scenario*/
	const char *scenarioname = parser->getParameter(SCENARIO,NAME);
	int numberOfExecutions = atoi(parser->getParameter(SCENARIO,NUMBER_OF_EXECUTIONS));
	long double scenarioSeed = atof(parser->getParameter(SCENARIO,SEED));
	
	Scenario *scene = new Scenario(scenarioname, j, g, numberOfExecutions, scenarioSeed);
	
	delete scenarioname;
	
	/*Set the scenario distribution values*/
	scene->setJobInputSize(atof(parser->getParameter(APPLICATION_INPUTSIZE,VALUE)));
	scene->setAverageTaskInputSize(atof (parser->getParameter(DATA_INPUT_GROUP, VALUE)));
	scene->setAverageTaskOutputSize(atof(parser->getParameter(DATA_OUTPUT_GROUP, VALUE)));
	scene->setInputHeterogeneity(atof(parser->getParameter(INPUT_AH, VALUE)));
	scene->setOutputHeterogeneity(atof(parser->getParameter(OUTPUT_AH, VALUE)));
	scene->setGridSpeed(atof(parser->getParameter(GRID_SPEED, VALUE)));
	scene->setGridHeterogeneity(atof(parser->getParameter(GRID_HETEROGENEITY, VALUE)));
	/*---------------------------*/
		
	/*Release memory used by parser*/
	delete this->parser;
	this->parser = NULL;
	
	return scene;
	
}

